package top.vanchor.myblog2back.controller.user.gameCenter;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;
import top.vanchor.myblog2back.entity.BlogUser;
import top.vanchor.myblog2back.entity.gameCenter.BlowUpPlaneBean;
import top.vanchor.myblog2back.service.IBlogChatService;
import top.vanchor.myblog2back.service.IBlogUserService;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Ding
 * @create 2022/1/10 20:37
 */
@Slf4j
@Component
@CrossOrigin
@RestController
@ServerEndpoint("/gameCenter/blowUpPlane/{sid}/{userId}")
public class BlowUpPlane {

    private static IBlogUserService iBlogUserService;

    private static IBlogChatService blogChatService;

    @Autowired
    public void setIBlogUserService(IBlogUserService iBlogUserService){
        BlowUpPlane.iBlogUserService = iBlogUserService;
    }

    @Autowired
    public void setIBlogUserService(IBlogChatService blogUserService){
        BlowUpPlane.blogChatService = blogUserService;
    }

    /**
     * 房间号 -> 组成员信息
     */
    private static ConcurrentHashMap<String, List<Session>> groupMemberInfoMap = new ConcurrentHashMap<>();
    /**
     * 房间号 -> 在线人数
     */
    private static ConcurrentHashMap<String, Set<Integer>> onlineUserMap = new ConcurrentHashMap<>();

    /**
     * 发送给指定用户
     * @param sid
     * @param userId
     * @param message
     * @throws IOException
     */
    public static void sendMessageTo(@PathParam("sid") String sid, @PathParam("userId") Integer userId, String message) throws IOException {
        List<Session> sessionList = groupMemberInfoMap.get(sid);
        Set<Integer> onlineUserList = onlineUserMap.get(sid);

        for (Session item : sessionList) {
            if (Integer.parseInt(String.valueOf(item.getRequestParameterMap().get("userId"))) == userId){
                try {
                    System.err.println("这是你要发送的用户");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }


    /**
     * 处理用户的请求，发送联机会话内容
     *
     * @param sid:房间号
     * @param userId：用户id
     * @param message：发送消息
     */
    @OnMessage
    public void onMessage(@PathParam("sid") String sid, @PathParam("userId") Integer userId, String message) {
        List<Session> sessionList = groupMemberInfoMap.get(sid);
        Set<Integer> onlineUserList = onlineUserMap.get(sid);
        /**
         * 封装信息体
         */
        BlogUser blogUser = iBlogUserService.getUserById(userId);
        BlowUpPlaneBean msg = JSONObject.parseObject(message, BlowUpPlaneBean.class);
        msg.setCount(onlineUserList.size());
        msg.setUsername(blogUser.getUName());
        msg.setAvatar(blogUser.getUAvatar());
        //判断对方是否在线
        if (onlineUserList.size() == 0){
            msg.setIsOnline(0);
        }else{
            Boolean isOnline = false;
            for (Integer integer : onlineUserList) {
                if (integer.equals(userId)){
                    isOnline = true;
                    break;
                }
            }
            msg.setIsOnline(isOnline==true?1:0);
        }
        //插入信息时间戳
        msg.setSendTime(String.valueOf((new Date()).getTime() / 1000));
        /**
         * 群发信息
         */
        sessionList.forEach(item -> {
            try {
                String text = JSONObject.toJSONString(msg);
                item.getBasicRemote().sendText(text);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });



    }

    /**
     * 建立连接调用的方法，群成员加入
     *
     * @param session
     * @param sid
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid, @PathParam("userId") Integer userId) {
        List<Session> sessionList = groupMemberInfoMap.computeIfAbsent(sid, k -> new ArrayList<>());
        Set<Integer> onlineUserList = onlineUserMap.computeIfAbsent(sid, k -> new HashSet<>());
        onlineUserList.add(userId);
        sessionList.add(session);
        // 发送上线通知
        sendInfo(sid, userId,onlineUserList.size(),1, "上线通知");
    }


    public void sendInfo(String sid, Integer userId,Integer onlineSum,Integer msgType, String info) {
        Set<Integer> onlineUserList = onlineUserMap.computeIfAbsent(sid, k -> new HashSet<>());

        // 获取该连接用户信息
        BlogUser blogUser = new BlogUser();
        try {
            blogUser = iBlogUserService.getUserById(userId);
        }catch (Exception e){
            e.printStackTrace();
        }
        // 发送通知
        BlowUpPlaneBean msg = new BlowUpPlaneBean();
        msg.setMsgType(msgType==null?0:msgType);
        msg.setCount(onlineSum);
        msg.setUserId(userId);
        msg.setAvatar(blogUser.getUAvatar());
        msg.setMsg(blogUser.getUName() + info);
        //判断对方是否在线
        if (onlineUserList.size() == 0){
            msg.setIsOnline(0);
        }else{
            Boolean isOnline = false;
            for (Integer integer : onlineUserList) {
                //为啥是userId，因为下线是下线者亲自申请的
                if (integer.equals(userId)){
                    isOnline = true;
                    break;
                }
            }
            msg.setIsOnline(isOnline==true?1:0);
        }
        //插入信息时间戳
        msg.setSendTime(String.valueOf((new Date()).getTime() / 1000));
        // json对象转字符串
        String text = JSONObject.toJSONString(msg);
        onMessage(sid, userId, text);
    }

    /**
     * 关闭连接调用的方法，群成员退出
     *
     * @param session
     * @param sid
     */
    @OnClose
    public void onClose(Session session, @PathParam("sid") String sid, @PathParam("userId") Integer userId) {

        List<Session> sessionList = groupMemberInfoMap.get(sid);
        sessionList.remove(session);
        Set<Integer> onlineUserList = onlineUserMap.get(sid);
        onlineUserList.remove(userId);
        // 发送离线通知
        sendInfo(sid, userId,onlineUserList.size(),2, "下线通知");
    }

    /**
     * 传输消息错误调用的方法
     *
     * @param error
     */
    @OnError
    public void OnError(Throwable error) {
        log.info("Connection error");
    }
}
